// 数据实验室相关服务
import api from '@/api/api';
import type { AxiosRequestConfig } from 'axios';

// 数据获取分析请求接口
export interface FetchAnalyzeRequest {
  url: string;
  headers?: Record<string, string>;
  params?: Record<string, any>;
  body?: Record<string, any>;
  method?: string;
  json_path?: string;
  group_by?: string;
  date_field?: string;
  freq?: string; // day, week, month
  value_field?: string;
  agg?: string; // count, sum, mean, max, min
}

// 导出Excel请求接口
export interface ExportExcelRequest {
  data: any[];
  columns?: string[];
}

// 分析结果接口
export interface AnalysisResult {
  aggregated_data?: any[];
  summary?: Record<string, any>;
  chart_data?: {
    xAxis: any[];
    series: any[];
  };
}

// 完整响应接口
export interface FetchAnalyzeResponse {
  status: string;
  timestamp: string;
  request_info: Record<string, any>;
  analysis: AnalysisResult;
  full_data: any[];
}

/**
 * 数据工具服务类
 */
class DataToolsService {
  /**
   * 获取并分析数据
   * @param request 请求参数
   * @returns 分析结果
   */
  async fetchAndAnalyze(request: FetchAnalyzeRequest): Promise<FetchAnalyzeResponse> {
    try {
      const response = await api.post<FetchAnalyzeResponse>('/v1/data/fetch_analyze', request);
      return response.data;
    } catch (error) {
      console.error('获取分析数据失败:', error);
      throw error;
    }
  }
  
  /**
   * 用于聊天界面的数据分析接口调用
   * @param params 分析参数
   * @returns 分析结果
   */
  async fetchAnalyze(params: any): Promise<any> {
    try {
      const response = await api.post('/v1/data/fetch_analyze', params);
      // 转换响应格式以符合聊天界面的需求
      const result = {
        statistics: response.data.analysis.summary || {},
        chart_data: response.data.analysis.chart_data || null,
        table_data: response.data.full_data || []
      };
      return result;
    } catch (error) {
      console.error('调用fetch_analyze失败:', error);
      throw error;
    }
  }

  /**
   * 导出Excel文件
   * @param request 导出请求参数
   * @returns Blob对象
   */
  async exportExcel(request?: ExportExcelRequest): Promise<any> {
    try {
      const response = await api.post('/v1/data/export_excel', request || {}, {
        responseType: 'blob'
      });
      
      // 为聊天界面创建下载URL
      const url = window.URL.createObjectURL(response.data);
      return {
        file_url: url,
        blob: response.data
      };
    } catch (error) {
      console.error('导出Excel失败:', error);
      throw error;
    }
  }

  /**
   * 下载Excel文件
   * @param blob 文件blob对象
   * @param filename 文件名
   */
  downloadExcel(blob: Blob, filename?: string): void {
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = filename || `数据导出_${new Date().toLocaleString('zh-CN').replace(/[\/\s:]/g, '_')}.xlsx`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url);
  }

  /**
   * 格式化数字
   * @param num 数字
   * @param decimals 小数位数
   * @returns 格式化后的字符串
   */
  formatNumber(num: number, decimals: number = 2): string {
    if (isNaN(num)) return '0';
    return num.toLocaleString('zh-CN', {
      minimumFractionDigits: decimals,
      maximumFractionDigits: decimals
    });
  }

  /**
   * 检测数据类型
   * @param value 值
   * @returns 类型字符串
   */
  detectType(value: any): 'string' | 'number' | 'boolean' | 'date' | 'object' | 'array' | 'null' {
    if (value === null) return 'null';
    if (Array.isArray(value)) return 'array';
    if (typeof value === 'object') {
      // 检查是否是日期
      if (value instanceof Date || (typeof value === 'string' && this.isDateString(value))) {
        return 'date';
      }
      return 'object';
    }
    if (typeof value === 'string' && this.isDateString(value)) {
      return 'date';
    }
    return typeof value as 'string' | 'number' | 'boolean';
  }

  /**
   * 判断字符串是否为日期格式
   * @param str 字符串
   * @returns 是否是日期
   */
  private isDateString(str: string): boolean {
    if (typeof str !== 'string') return false;
    
    // 尝试解析常见的日期格式
    const dateRegexes = [
      /^\d{4}-\d{2}-\d{2}$/, // YYYY-MM-DD
      /^\d{4}\d{2}\d{2}$/, // YYYYMMDD
      /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/, // ISO格式
      /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/ // 中国格式
    ];
    
    // 先检查正则匹配
    const matchesRegex = dateRegexes.some(regex => regex.test(str));
    if (!matchesRegex) return false;
    
    // 再检查是否能被解析为有效的日期
    const date = new Date(str);
    return !isNaN(date.getTime());
  }

  /**
   * 从数据中提取所有字段名
   * @param data 数据列表
   * @returns 字段名列表
   */
  extractFields(data: any[]): string[] {
    if (!Array.isArray(data) || data.length === 0) return [];
    
    const fields = new Set<string>();
    
    const extractNestedFields = (obj: any, prefix: string = '') => {
      if (typeof obj !== 'object' || obj === null || Array.isArray(obj)) return;
      
      Object.keys(obj).forEach(key => {
        const fieldName = prefix ? `${prefix}.${key}` : key;
        
        // 只收集基本类型的字段
        const valueType = this.detectType(obj[key]);
        if (['string', 'number', 'boolean', 'date'].includes(valueType)) {
          fields.add(fieldName);
        } else if (valueType === 'object') {
          // 递归提取嵌套对象的字段
          extractNestedFields(obj[key], fieldName);
        }
      });
    };
    
    // 遍历数据，提取字段
    data.forEach(item => {
      if (typeof item === 'object' && item !== null && !Array.isArray(item)) {
        extractNestedFields(item);
      }
    });
    
    return Array.from(fields).sort();
  }
}

// 导出单例
export default new DataToolsService();
